export default function control () {
  const box = document.createElement('div');
  box.className = 'clipper_control';

  let btns = '<span class="cli_ok"></span>';

  if (this.cfg.btns) {
    btns = this.cfg.btns.map((t, i) => {
      return `<span class="cli_btn" data-id="${ i }">${ t.name }</span>`;
    }).join('');
  }

  const html = `
    <div class="cli_inner">
      <i class="cli_view">
        <img class="cli_view_img" style="
          top: ${ this.imgCli.top }px;
          left: ${ this.imgCli.left}px;
          width: ${ this.imgCli.width }px;
          height: ${ this.imgCli.height }px;
      " src="${ this.image.src }">
      </i>

      <i class="cli_top"></i>
      <i class="cli_right"></i>
      <i class="cli_bottom"></i>
      <i class="cli_left"></i>

      <i class="cli_p_1"></i>
      <i class="cli_p_2"></i>
      <i class="cli_p_3"></i>
      <i class="cli_p_4"></i>

      <i class="cli_center"></i>

      <div class="cli_keyboard">
        <span class="cli_cancel"></span>
        ${ btns }
      </div>
      <div class="cli_num"></div>
    </div>
  `;

  box.innerHTML = html;

  let beforePoint = null;
  let select = null;

  const mousedown = e => {
    e.preventDefault();

    this.isDown = true;
    select = e.target.className;
    beforePoint = null;
  }

  const mouseup = e => {
    e.preventDefault();

    this.isDown = false;
    select = null;
  }

  const mousemove = e => {
    e.preventDefault();

    if (!this.isDown) {
      return;
    }

    let top = 0, left = 0, bottom = 0, right = 0;
    let resetFlag = false;

    let y = e.clientY - this.client.top >> 0;
    let x = e.clientX - this.client.left >> 0;

    x < 0 && (x = 0);
    x > this.client.width && (x = this.client.width);
    y < 0 && (y = 0);
    y > this.client.height && (y = this.client.height);

    if (!beforePoint) {
      beforePoint = { x, y, ...this.points };
      return;
    }

    const maxTop = this.client.height - beforePoint.height;
    const maxLeft = this.client.width - beforePoint.width;

    // inner
    if (/cli_inner|cli_center/.test(select)) {
      top = y - (beforePoint.y - beforePoint.top);
      left = x - (beforePoint.x - beforePoint.left);

      top < 0 && (top = 0);
      top > maxTop && (top = maxTop);
      left < 0 && (left = 0);
      left > maxLeft && (left = maxLeft);

      this.points.top = top;
      this.points.left = left;

      resetFlag = true;
    }

    // top
    if (/cli_top|cli_p_1|cli_p_2/.test(select)) {
      bottom = beforePoint.height + beforePoint.top;

      if (y < bottom) {
        top = y
      } else {
        top = bottom;
        bottom = y;
      }

      this.points.top = top;
      this.points.height = Math.abs(bottom - top);

      resetFlag = true;
    }

    // bottom
    if (/cli_bottom|cli_p_4|cli_p_3/.test(select)) {
      top = beforePoint.top;

      if (y > top) {
        bottom = y
      } else {
        bottom = top;
        top = y;
      }

      this.points.top = top;
      this.points.height = Math.abs(bottom - top);

      resetFlag = true;
    }

    // left
    if (/cli_left|cli_p_1|cli_p_4/.test(select)) {
      right = beforePoint.left + beforePoint.width;

      if (x < right) {
        left = x
      } else {
        left = right;
        right = x;
      }

      this.points.left = left;
      this.points.width = Math.abs(right - left);

      resetFlag = true;
    }

    // right
    if (/cli_right|cli_p_2|cli_p_3/.test(select)) {
      left = beforePoint.left;

      if (x > left) {
        right = x
      } else {
        right = left;
        left = x;
      }

      this.points.left = left;
      this.points.width = Math.abs(right - left);

      resetFlag = true;
    }

    if (resetFlag) {
      return init();
    }

    // 绘制

    if (x < beforePoint.x) {
      left = x;
      right = beforePoint.x;
    }

    if (y < beforePoint.y) {
      top = y;
      bottom = beforePoint.y;
    }

    if (x >= beforePoint.x) {
      left = beforePoint.x;
      right = x;
    }

    if (y >= beforePoint.y) {
      top = beforePoint.y;
      bottom = y;
    }

    this.points = {
      top,
      left,
      width: right - left,
      height: bottom - top
    };

    init();
  }

  const clickHandle = (e) => {
    const type = e.target.className;
    const btnId = e.target.getAttribute('data-id');

    if (btnId) {
      this.cfg.btns[+btnId].click.bind(this)();
      return;
    }

    if (/cli_ok/.test(type)) {
      this.createCanvas();
    }

    if (/cli_cancel/.test(type)) {
      this.cfg.cancel && this.cfg.cancel() || this.destroy();
    }
  };

  this.con.onmousedown = mousedown;
  this.con.onmouseup = mouseup;
  this.con.onmousemove = mousemove;
  this.con.onmouseleave = mouseup;
  this.con.onclick = clickHandle;

  // 生成图片
  const createImageScene = () => {
    const { top, left, width, height } = this.imgCli;
    const mask = document.createElement('div');

    mask.className = 'clipper_mask';
    mask.innerHTML = `
      <img class="clipper_image" style="
        top: ${ top }px;
        left: ${ left}px;
        width: ${ width }px;
        height: ${ height }px;
      " src="${ this.cfg.image }"/>
    `;

    return mask;
  };

  const imageScene = createImageScene();

  const init = () => {
    if (!(this.points instanceof Object)) {
      return;
    }

    const { top, left, width, height } = this.points;

    const view = box.querySelector('.cli_view_img');
    const num = box.querySelector('.cli_num');

    box.style.display = 'block';
    box.style.width = `${ width }px`;
    box.style.height = `${ height }px`;
    box.style.transform = `translateX(${ left }px) translateY(${ top }px)`;

    view.style.transform = `translateX(${ -left }px) translateY(${ -top }px)`;
    num.innerHTML = `${ width >> 0 } x ${ height >> 0 }`;
  }

  // 自动生成
  if (typeof this.cfg.openSize === 'number') {
    const oz = this.cfg.openSize;
    const width = this.imgCli.width * oz >> 0;
    const height = this.imgCli.height * oz >> 0;
    const top = this.imgCli.top + (this.imgCli.height - height)/2;
    const left = this.imgCli.left + (this.imgCli.width - width)/2;

    this.points = { top, left, width, height };

    init();
  }

  this.con.appendChild(imageScene);
  this.con.appendChild(box);
  return box;
}
